//
//  "$Id: AudioEnc.h 91860 2012-12-08 09:18:30Z li_weijun $"
//
//  Copyright (c)1992-2007, ZheJiang Dahua Technology Stock CO.LTD.
//  All Rights Reserved.
//
//	Description:	
//	Revisions:		Year-Month-Day  SVN-Author  Modification
//

#ifndef __AUDIO_ENC_API_H__
#define __AUDIO_ENC_API_H__

#include "Types.h"
#include "Defs.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup AudioEncAPI API Audio Encoder
/// 音频数据编码接口，用于通道音频数据编码，语音对讲等等。
/// \n 调用流程图:
/// \code
///    =========================================
///                   |                         
///            createAudioEncoder                  
///                   |                         
///                addRef                  
///                   |
///               setFormat
///                   |        	 
///                 start
///         +---------|----------------+
///         |     getPacket        setVolume      	 
///         |   releasePacket          |        	 
///         +---------|----------------+           	
///                 stop
///                   |
///               release                  
///                   |                         
///    =========================================
/// \endcode
/// @{

/// 音频编码格式
typedef enum AudioEncType
{
	audioEncPCM = 0,
	audioEncADPCM,
	audioEncG711A,
	audioEncG711Mu,
	audioEncG726,
	audioEncMPEG2Layer1,
	audioEncAMR,
	audioEncAAC,
	audioEncG726ASF
} AudioEncType;

/// 输入声音质量增强功能
typedef enum AudioVqeType
{
	audioVqeAec = 0,	///< 回声抵消
	audioVqeAnr,		///< 降噪功能
	audioVqeAlc,		///< 自动增益
	audioVqeHpf,		///< 高通滤波
	audioVqeRnr			///< 录音噪声消除
} AudioVqeType;

/// AMR编码模式
enum AMRMode
{
	AMR475 = 0,
	AMR515,
	AMR59,
	AMR67,
	AMR74,
	AMR795,
	AMR102,
	AMR122, 
};

/// 音频编码设备特性，128字节
typedef struct AudioEncCaps
{
	/// 支持的压缩标准的掩码，位序号对应枚举类型AudioEncType的每一个值。
	/// 置位表示支持该枚举值对应的特性，清零表示不支持。
	ulong types;

	/// 前端支持的音频编码格式的组合方式数目，具体参数组合使用getFormatCaps接口函数获取。
	char formatCount;

	/// 保留
	char reserved1[3];

	/// 支持的声音质量增强功能的掩码，位序号对应枚举类型AudioVqeType的每一个值。
	/// 置位表示支持该枚举值对应的特性，清零表示不支持。
	ulong vqeTypes;

	/// 保留
	int	reserved[29];
} AudioEncCaps;


/// 音频帧打包格式
typedef enum AudioEncPackType
{
    audioEncPackTypeRAW = 0,    ///< 裸码流，不打包
    audioEncPackTypeADTS= 1,    ///< AAC-ADTS格式打包
	audioEncPackTypeZLAV,	    ///< ZLAV格式打包
	audioEncPackTypePS,			///< PS流格式打包
	
}AudioEncPackType;

/// 音频编码格式，128字节
typedef struct AudioEncFormat
{
	AudioEncType	type;				///< 音频编码的类型
	int				frequency;			///< 采样率，Hz为单位，比如44100Hz	
	int				depth : 8;			///< 采样位深，支持8位，16位
	int				packetPeriod : 8;	///< 打包周期，ms为单位，如10ms，20ms，0表示使用默认周期
	int				mode : 8;			///< 工作模式，不同编码类型定义不同。
	AudioEncPackType pack : 8;			///< 打包格式
	uchar			specLength;			///< 包含的CodecSpecInfo数据长度，如果为0则表示无效
	uchar			*specBuffer;		///< CodecSpecInfo具体信息
	unsigned int    channelNum;         ///< 声道数
	int				reserved[26];		///< 保留
} AudioEncFormat;

///音质增强, 128字节
typedef struct
{
	int enableAec;		///< 是否开启回声抵消, 1-开启， 0-不开启
	int enableAnr;		///< 是否开启降噪功能, 1-开启， 0-不开启
	int enableAlc;		///< 是否开启自动增益, 1-开启， 0-不开启
	int enableHpf;		///< 是否开启高通滤波, 1-开启， 0-不开启
	int enableRnr;		///< 是否开启噪声消除, 1-开启， 0-不开启
	int	reserved[27];	///< 保留
}AudioVqeAttr;

/// 音频编码包，128字节
typedef struct AudioEncPacket
{
	uchar *			buffer;		///< 数据缓冲指针
	ulong			length;		///< 数据缓冲有效长度
	uint64			pts;		///< 时间戳(jiffies_64*(1000/HZ))，ms为单位
	ulong			sequence;	///< 帧序号，用于校验是否丢帧
	char			head;		///< 是否包含帧头，1-包含，0-不包含
	char			tail;		///< 是否包含帧尾，1-包含，0-不包含
	char			newFormat;	///< 编码格式是否发生了变动，0：未变动，1：已变动
	char			remain;		///< 除了这个数据包，是否还有本帧或其他帧的后续数据可以获取
	ulong			utc;		///< 帧内音频对应的UTC(1970-1-1 00:00:00)秒数
	ushort			utcms;		///< UTC时间对应的毫秒数
	uint64			ptsBeforeEnc;///< 编码前的时间戳(jiffies_64*(1000/HZ))
	uint64			ptsAfterEnc;///< 编码后的时间戳(jiffies_64*(1000/HZ))
	uint64			ptsLib;		///< 编码库从驱动取到本数据包的时间戳(jiffies_64*(1000/HZ))
	int				reserved[18];///< 保留
}AudioEncPacket;

typedef struct _Audio_ChnAttr
{
	int mic_sampleRate;
	int mic_channels;
	int line_sampleRate;
	int line_channels;
	int reserved[4];
}_Audio_ChnAttr;

/// 音频编码接口，512字节
typedef struct AudioEncoder
{
	/// 底层私有数据
	void *priv;


	/// 增加接口引用
	int (*addRef)(struct AudioEncoder *thiz);


	/// 释放接口
	int (*release)(struct AudioEncoder *thiz);


	/// 得到音频编码支持的特性。
	///
	/// \param [in] thiz 本对象指针
	/// \param [out] caps 指向音频编码特性结构AudioEncCaps的指针。
	/// \retval 0  获取成功。
	/// \retval <0  获取失败。
	int (*getCaps)(struct AudioEncoder *thiz, AudioEncCaps * caps);


	/// 开始音频编码
	///
	/// \param [in] thiz 本对象指针
	/// \retval <0 开始失败
	/// \retval 0 开始成功
	int (*start)(struct AudioEncoder *thiz);


	/// 停止音频编码
	///
	/// \param [in] thiz 本对象指针
	/// \retval <0 停止失败
	/// \retval 0 停止成功
	int (*stop)(struct AudioEncoder *thiz);


	/// 读取编码数据，读为非阻塞模式；每次传出一个连续的数据块，如果数据已经分块，
	/// 则分多次传出。如果没有数据，则返回错误。
	///
	/// \param [in] thiz 本对象指针
	/// \param [in] packet 音频包结构AudioEncPacket指针。
	/// \return>=0 通道号（在输入通道号为-1时）
	/// \retval 0  读成功
	/// \retval <0  读失败
	int (*getPacket)(struct AudioEncoder *thiz, AudioEncPacket * packet);


	/// 释放采样数据
	/// \param [in] thiz 本对象指针
	int (*releasePacket)(struct AudioEncoder *thiz);


	/// 设置音频数据编码的格式。
	///
	/// \param [in] thiz 本对象指针。
	/// \param [in] format 指向音频编码格式结构AudioEncFormat的指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setFormat)(struct AudioEncoder *thiz, AudioEncFormat * format);


	/// 设置音频编码的音量。
	///
	/// \param [in] thiz 本对象指针。
	/// \param [in] volume 音量，取值0-100。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setVolume)(struct AudioEncoder *thiz, int volume);


	/// 获取音频编码支持的格式列表，应用层必须从支持的列表中选择一项作为setFormat接口的输入参数。
	/// 
	/// \param [in] thiz 本对象指针。
	/// \param [out] formats 格式结构AudioEncFormat数组，数组长度必须足以放下
	///         所有支持的格式列表。支持的格式数目用AudioEncCaps::formatCount表示。
	///			每个AudioEncFormat结构中的type、frequency、depth参数表示一个有效的编码参数组合，
	///			其他参数忽略。
	/// \retval 0  获取成功
	/// \retval <0  获取失败
	int (*getFormatCaps)(struct AudioEncoder *thiz, AudioEncFormat* formats);	


	/// 使用 DMA 复制编码数据,若函数指针为空表示不支持DMA拷贝。
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] dst 目标内存地址
	/// \param [in] src 源数据内存地址，这个是从 getPacket 中取得的地址
	/// \param [in] len 源数据长度
	/// \retval 0  成功
	/// \retval <0  失败
	int (*dmaCopy)(struct AudioEncoder *thiz, void* dst, void* src, unsigned int len);

	/// 设置音质增强功能
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] vqeAttr格式结构体指针 AudioVqeAttr
	/// \retval 0  成功
	/// \retval <0	失败
	int (*setVqeAttr)(struct AudioEncoder *thiz, AudioVqeAttr *vqeAttr);

	/// 发送数据到ao模块
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] pData 音频指针
	/// \param [in] len 音频长度
	/// \retval 0  成功
	/// \retval <0	失败
	int (*sendPacketToAo)(struct AudioEncoder *thiz, char *pData, int len);

    /// 发送裸音频数据到编码模块
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] pBuf 音频裸指针
	/// \param [in] len 音频长度
	/// \param [in] pts 时间戳
	/// \retval 0  成功
	/// \retval <0	失败
	int (*putAudioRawData)(struct AudioEncoder *pThiz, char *pBuf, int len, uint64 pts);

    /// 获取音频编码数据需要的解码信息
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] ppBuffer 解码信息裸指针的指针
	/// \param [in] pSize 解码信息长度
	/// \retval 0  成功
	/// \retval <0	失败
	int (*getSpecificInfo)(struct AudioEncoder *pThiz, char **ppBuffer, unsigned long *pSize);
	
	/// 保留
	void* reserved[113];
} AudioEncoder;

/// 码流类型
typedef enum AudioEncStream
{
	audioEncStream0 = 0,
	audioEncStream1,
	audioEncStream2,
	audioEncStream3,
	audioEncStream4,
	audioEncStream5,
	audioEncStream6,
	audioEncStream7,
	audioEncStreamNumber	///< 种类数
} AudioEncStream;

/// 音频编码接口描述，128字节
typedef struct AudioEncDesc
{
	ulong			srcs;		///< 音频输入物理通道号掩码，每一位对应一个音频输入通道			
	AudioEncStream	stream;		///< 指定编码码流的类型
	int				card;	    ///< 子卡槽位号，0表示主板，>0表示子卡
	int				channel;		  ///< 音频编码通道号
	int 			reserved[28];     ///< 保留
} AudioEncDesc;

typedef struct 
{
	int aiChn;
	int aiSampleRate;
	int aiSampleNum;
	int aoChn;
	int aoSampleRate;
	int aoSampleNum;
}Audio_uac_card_info;


/// 创建音频编码接口
///
/// \param [in] desc 音频编码接口描述结构AudioEncDesc指针
/// \param [out] audioEncoder 音频编码接口指针的指针
/// \retval <0 创建失败
/// \retval 0 创建成功
int PAL_API createAudioEncoder(AudioEncDesc *desc, AudioEncoder **audioEncoder);


/// @} end of group

#ifdef __cplusplus
}
#endif

#endif //__AUDIO_ENC_API_H__

